<html>
<head><meta charset="utf-8"><title>indeterministic proc-macro · t-compiler/rust-analyzer · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/index.html">t-compiler/rust-analyzer</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/indeterministic.20proc-macro.html">indeterministic proc-macro</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="196602201"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/indeterministic%20proc-macro/near/196602201" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Edwin Cheng <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/indeterministic.20proc-macro.html#196602201">(May 06 2020 at 08:26)</a>:</h4>
<p>I have read some articles written by <span class="user-mention" data-user-id="133169">@matklad</span> that some proc-macro are impossible to infer and analysis. But I am tracing a bug in some proc-macros that is indeterministic: i.e. It expands to different syntax orders every time( maybe using Hashmap internally)</p>



<a name="196602238"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/indeterministic%20proc-macro/near/196602238" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/indeterministic.20proc-macro.html#196602238">(May 06 2020 at 08:27)</a>:</h4>
<p>Hm, yeah, that would be bad for salsa...</p>



<a name="196602250"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/indeterministic%20proc-macro/near/196602250" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/indeterministic.20proc-macro.html#196602250">(May 06 2020 at 08:27)</a>:</h4>
<p>Dear, we do need to wasm up all proc macros...</p>



<a name="196602419"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/indeterministic%20proc-macro/near/196602419" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Florian Diebold <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/indeterministic.20proc-macro.html#196602419">(May 06 2020 at 08:29)</a>:</h4>
<blockquote>
<p>wasm up all proc macros</p>
</blockquote>
<p>there's also the new WinRT integration that uses proc macros to generate bindings on the fly, reading lots of files in the process <span aria-label="grimacing" class="emoji emoji-1f62c" role="img" title="grimacing">:grimacing:</span></p>



<a name="196602622"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/indeterministic%20proc-macro/near/196602622" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Florian Diebold <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/indeterministic.20proc-macro.html#196602622">(May 06 2020 at 08:31)</a>:</h4>
<p>but I guess as long as the binding files don't change, that's maybe not the worst</p>



<a name="196602751"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/indeterministic%20proc-macro/near/196602751" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/indeterministic.20proc-macro.html#196602751">(May 06 2020 at 08:32)</a>:</h4>
<p>Yea, I've already left a "please, don't" comment on their repo: <a href="https://github.com/microsoft/winrt-rs/issues/107#issuecomment-622402448" title="https://github.com/microsoft/winrt-rs/issues/107#issuecomment-622402448">https://github.com/microsoft/winrt-rs/issues/107#issuecomment-622402448</a> :D</p>



<a name="196603082"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/indeterministic%20proc-macro/near/196603082" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Edwin Cheng <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/indeterministic.20proc-macro.html#196603082">(May 06 2020 at 08:36)</a>:</h4>
<p>I know they are starting to discuss about 2021 edition features, you might have to persuade to them hardly.</p>



<a name="196603131"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/indeterministic%20proc-macro/near/196603131" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Edwin Cheng <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/indeterministic.20proc-macro.html#196603131">(May 06 2020 at 08:37)</a>:</h4>
<p>FYI, the actual panic is look like this :</p>
<div class="codehilite"><pre><span></span><code>thread &#39;&lt;unnamed&gt;&#39; panicked at &#39;can&#39;t resolve local ptr to SyntaxNode: SyntaxNodePtr { range: 160..329, kind: IMPL_DEF }&#39;, crates\ra_syntax\src\ptr.rs:30:28
</code></pre></div>



<a name="196603141"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/indeterministic%20proc-macro/near/196603141" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/indeterministic.20proc-macro.html#196603141">(May 06 2020 at 08:37)</a>:</h4>
<p>I don't think it's a good idea to target any lang-changes for 2021 edition -- not enough time</p>



<a name="196603161"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/indeterministic%20proc-macro/near/196603161" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/indeterministic.20proc-macro.html#196603161">(May 06 2020 at 08:37)</a>:</h4>
<p>for 2024, I hope we'll be able to clean up the lang with an eye towards IDE</p>



<a name="196603342"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/indeterministic%20proc-macro/near/196603342" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Edwin Cheng <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/indeterministic.20proc-macro.html#196603342">(May 06 2020 at 08:39)</a>:</h4>
<p>Okay, then we have to hotfix this bug now :(<br>
I propose we store a cache for expansion result, and return its for second call for <code>expand_proc_macro</code></p>



<a name="196603384"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/indeterministic%20proc-macro/near/196603384" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/indeterministic.20proc-macro.html#196603384">(May 06 2020 at 08:39)</a>:</h4>
<p>Maybe we should move proc-macros to a separate table, which is not LRUd?</p>



<a name="196603630"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/indeterministic%20proc-macro/near/196603630" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Edwin Cheng <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/indeterministic.20proc-macro.html#196603630">(May 06 2020 at 08:42)</a>:</h4>
<p>Thats much better of course. </p>
<p>But would you mind give me some pointer about that part of doc in salsa ? I  know very basic usage about it.</p>



<a name="196603817"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/indeterministic%20proc-macro/near/196603817" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/indeterministic.20proc-macro.html#196603817">(May 06 2020 at 08:44)</a>:</h4>
<p>Seems like we have zero docs about this D:</p>



<a name="196603954"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/indeterministic%20proc-macro/near/196603954" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/indeterministic.20proc-macro.html#196603954">(May 06 2020 at 08:46)</a>:</h4>
<p>wait, where do we actually set up LRU? Looks like I forgot how it works</p>



<a name="196604005"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/indeterministic%20proc-macro/near/196604005" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/indeterministic.20proc-macro.html#196604005">(May 06 2020 at 08:47)</a>:</h4>
<p>Ah, it's well hidden. <span class="user-mention" data-user-id="216201">@Edwin Cheng</span> take a look at <code>RootDatabase::update_lru_capacity</code> method</p>



<a name="196604014"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/indeterministic%20proc-macro/near/196604014" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/indeterministic.20proc-macro.html#196604014">(May 06 2020 at 08:47)</a>:</h4>
<p>It calls <code>self.query_mut(ra_db::ParseQuery).set_lru_capacity(lru_capacity);</code></p>



<a name="196604044"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/indeterministic%20proc-macro/near/196604044" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/indeterministic.20proc-macro.html#196604044">(May 06 2020 at 08:47)</a>:</h4>
<p>What this does, in terms of salsa, is ensures that at any time there's at most <code>lru_capacity</code> <strong>values</strong> in a given table</p>



<a name="196604078"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/indeterministic%20proc-macro/near/196604078" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/indeterministic.20proc-macro.html#196604078">(May 06 2020 at 08:48)</a>:</h4>
<p>and values are evicted on LRU bases</p>



<a name="196604124"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/indeterministic%20proc-macro/near/196604124" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/indeterministic.20proc-macro.html#196604124">(May 06 2020 at 08:48)</a>:</h4>
<blockquote>
<p>I know very basic usage about it.</p>
</blockquote>
<p>I think you might want to spend some time reading the source code for salsa -- it's a very interesting and well-writen piece of technology :)</p>



<a name="196604724"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/indeterministic%20proc-macro/near/196604724" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Edwin Cheng <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/indeterministic.20proc-macro.html#196604724">(May 06 2020 at 08:55)</a>:</h4>
<p>Will do! Thanks</p>



<a name="196605276"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/indeterministic%20proc-macro/near/196605276" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pksunkara <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/indeterministic.20proc-macro.html#196605276">(May 06 2020 at 08:59)</a>:</h4>
<p>I agree. I had fun reading up on rust-analyzer salsa stuff :D</p>



<a name="196663603"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/indeterministic%20proc-macro/near/196663603" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/indeterministic.20proc-macro.html#196663603">(May 06 2020 at 16:52)</a>:</h4>
<p><span class="user-mention" data-user-id="133169">@matklad</span> just to scare you more, pest currently also reads from another file in its derive macro (though we do offer an inline option now).</p>



<a name="196663725"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/indeterministic%20proc-macro/near/196663725" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/indeterministic.20proc-macro.html#196663725">(May 06 2020 at 16:53)</a>:</h4>
<p>I'm slowly pushing for a <code>proc_macro</code> API for loading a file (with the Rust lexer and getting <code>Span</code> information) which should be less problematic than just reading an arbitrary file, though.</p>



<a name="196663759"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/indeterministic%20proc-macro/near/196663759" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/indeterministic.20proc-macro.html#196663759">(May 06 2020 at 16:53)</a>:</h4>
<p>(because it tells the macro driver to do the file loading)</p>



<a name="196663937"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/indeterministic%20proc-macro/near/196663937" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/indeterministic.20proc-macro.html#196663937">(May 06 2020 at 16:54)</a>:</h4>
<p>Basically, <code>fn proc_macro::open(&amp;Path) -&gt; TokenStream</code>.</p>



<a name="196664019"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/indeterministic%20proc-macro/near/196664019" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Florian Diebold <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/indeterministic.20proc-macro.html#196664019">(May 06 2020 at 16:55)</a>:</h4>
<p>if it returns a <code>TokenStream</code>, it can only be used for files that can be lexed as Rust though, right?</p>



<a name="196664080"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/indeterministic%20proc-macro/near/196664080" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/indeterministic.20proc-macro.html#196664080">(May 06 2020 at 16:56)</a>:</h4>
<p>Yes, but I think that's the majority of cases</p>



<a name="196664159"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/indeterministic%20proc-macro/near/196664159" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/indeterministic.20proc-macro.html#196664159">(May 06 2020 at 16:56)</a>:</h4>
<p>And I'm also in favor of making <code>TokenStream</code> able to represent invalid tokens</p>



<a name="196664292"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/indeterministic%20proc-macro/near/196664292" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/indeterministic.20proc-macro.html#196664292">(May 06 2020 at 16:57)</a>:</h4>
<p>(by e.g. making "2.0" <code>meta::tokens::TokenStream</code> closer to <code>rustc_lexer</code> than <code>proc_macro::TokenStream</code> would be one "simple" way of doing so)</p>



<a name="196743899"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/indeterministic%20proc-macro/near/196743899" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pksunkara <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/indeterministic.20proc-macro.html#196743899">(May 07 2020 at 09:05)</a>:</h4>
<p>I have a proc_macro that processes a lot of files using regex (not <code>TokenStream</code>) and builds a <code>TokenStream</code>. I understand that this is bad practice, but I couldn't achieve this any other way. What exactly do we need to support this in the IDE? Maybe some kind of flag to denote a proc_macro as indeterministic? That would allow the proc_macro server to run it everytime.</p>



<a name="196746456"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/indeterministic%20proc-macro/near/196746456" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Edwin Cheng <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/indeterministic.20proc-macro.html#196746456">(May 07 2020 at 09:32)</a>:</h4>
<p>I can imagine the wasm proc-macro should be <code>no-std</code> with some explict api for IO and other stuffs. In theory we could hook the IO api in wasm VM and detect if anything is changed in expansion and invalidate all related caches. </p>
<p>But well, it is quite complicated ...</p>



<a name="196832671"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/indeterministic%20proc-macro/near/196832671" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/indeterministic.20proc-macro.html#196832671">(May 07 2020 at 21:28)</a>:</h4>
<p>A small step would just to be allowing proc macros to use <code>cargo:rerun-if-changed</code> like build scripts do.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>